package my.convert.attribute.processor;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

public abstract class AttributeProcessor {
	/**
	 * 功能：处理类中的属性，把属性名和属性类型，按spring表单传值的规则，映射起来，放入mapper集合中，并反回该mapper。
	 * @param entityClazz
	 * @param mapper
	 * @return
	 */
	public abstract Map<String,Class<?>> execute(Class<?> entityClazz,Map<String,Class<?>> mapper);
	/**
	 * 得到实体中所有有setter方法的属性。
	 * @param cls
	 * @return
	 */
	protected List<Field> parseEntry(Class<?> entityClass) {
		ArrayList<Field> list = new ArrayList<Field>();
		Field[] allField = this.getAllFields(entityClass);
		Method m = null;
		String methodName; 
		StringBuilder sb = new StringBuilder();
		for (Field f : allField) {
			methodName = f.getName();
			sb.delete(0, sb.length());
			sb.append("set").append(methodName.substring(0, 1).toUpperCase()).append(methodName.substring(1));
			methodName = sb.toString();
			try {
				Class clazz = entityClass;
				// 只返回和当前字段类型相符的set方法，不支持多参数以及不同类型的set方法
				while(m==null && clazz!=null) {
					try {
						m = clazz.getDeclaredMethod(methodName, f.getType());
					} catch (Exception e) {
					}
					clazz = clazz.getSuperclass();
				}
				
				if (m != null) {
					list.add(f);
				}
			} catch (Exception e) {
				// TODO NoSuchMethodException
			}
		}
		sb = null;
		methodName = null;
		allField = null;
		return list;
	}
	private  Field[] getAllFields(Class clazz){
		  List<Field> fieldList = new ArrayList<>();
		  while (clazz != null){
		    fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
		    clazz = clazz.getSuperclass();
		  }
		  Field[] fields = new Field[fieldList.size()];
		  fieldList.toArray(fields);
		  return fields;
	}
	private  Field getField(Class clazz,String fieldName){
		Field declaredField = null;
		while (declaredField == null &&  clazz != null){
			try {
				declaredField = clazz.getDeclaredField(fieldName);
			} catch (NoSuchFieldException e) {
			} 
			clazz = clazz.getSuperclass();
		}
		return declaredField;
	}
}
